// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "MotionAnimInfos.h"
#include "Layers/MotionSubtitlesLayerBase.h"
#include "Actions/ActionBase.h"
#include "UObject/Object.h"
#include "MotionSubtitlesAnimPlayer.generated.h"

/**
 * 
 */
UENUM(BlueprintType)
enum class EAnimPlayerState:uint8
{
	None,
	Initialized,
	Enter,
	Stay,
	Exit,
	Done
};

USTRUCT(BlueprintType)
struct MOTIONSUBTITLES_API FAnimAttributes
{
	GENERATED_USTRUCT_BODY()

	TArray<FMotionAnimInfo> EnterAnimations;
	TArray<FMotionAnimInfo> StayAnimations;
	TArray<FMotionAnimInfo> ExitAnimations;
	TArray<TWeakObjectPtr<UMotionSubtitlesLayerBase>> Layers;
	float Duration;
};

USTRUCT(BlueprintType)
struct MOTIONSUBTITLES_API FActionAttributes
{
	GENERATED_USTRUCT_BODY()

	TArray<FAnimActionInfo> EnterAnimations;
	TArray<FAnimActionInfo> StayAnimations;
	TArray<FAnimActionInfo> ExitAnimations;
	TArray<TWeakObjectPtr<UMotionSubtitlesLayerBase>> Layers;
	float Duration;
};

class FMotionSubtitlesAnimPlayer
{
private:
	EAnimPlayerState PlayerState = EAnimPlayerState::None;
	
	TArray<TSharedPtr<FActionBase>> EnterActions;
	TArray<TSharedPtr<FActionBase>> StayActions;
	TArray<TSharedPtr<FActionBase>> ExitActions;
	TArray<TSharedPtr<FActionBase>> CurrentActions;

	float EnterDuration = 0;
	float ExitDuration = 0;
	float StayDuration = 0;

	float Timer = 0;

public:
	void Init(const FAnimAttributes& AnimAttributes);
	void Tick(float DeltaTime);
	void Exit();

private:
	void Reset();
	void CreateActionAttributes(const FAnimAttributes& AnimAttributes,FActionAttributes& ActionAttributes);
	void CreateActionAttributes(const TArray<FMotionAnimInfo>& AnimInfos,
	                             const TArray<TWeakObjectPtr<UMotionSubtitlesLayerBase>>& Layers,
	                             TArray<FAnimActionInfo>& ActionInfos);
	
	void SwitchState(const EAnimPlayerState& NewState);
	void CreateActions(const FActionAttributes& ActionAttributes);
	void CreateActions(const TArray<FAnimActionInfo>& ActionInfos, TArray<TSharedPtr<FActionBase>>& Actions);
	float CalcStateDuration(const TArray<FAnimActionInfo>& ActionInfos);
	void ScaleActions(FActionAttributes& ActionAttributes);
	void ScaleStateDuration(const float OriginStateDuration, const float OriginTotalDuration, float& RealStateDuration,
	                        const float RealDuration, TArray<FAnimActionInfo>& ActionInfos);
	void ScaleStateDuration(const float ScaleRate, TArray<FAnimActionInfo>& ActionInfos,bool AlwaysScaleStartOffset = false);
};
